<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="ssdut dsa web" />
    <meta name="author" content="" />

    <title>ssdut.DSA/图/最小生成树</title>
    <link rel="stylesheet" href="../assets/css/fonts/linecons/css/linecons.css">
    <link rel="stylesheet" href="../assets/css/fonts/fontawesome/css/font-awesome.min.css">
    <link rel="stylesheet" href="../assets/css/bootstrap.css">
    <link rel="stylesheet" href="../assets/css/xenon-core.css">
    <link rel="stylesheet" href="../assets/css/xenon-forms.css">
    <link rel="stylesheet" href="../assets/css/xenon-components.css">
    <link rel="stylesheet" href="../assets/css/xenon-skins.css">
    <link rel="stylesheet" href="../assets/css/custom.css">
    <link rel="stylesheet" type="text/css" href="../assets/css/stylesheet.css">
    <link rel="stylesheet" type="text/css" href="../assets/css/common.css">
    <link rel="stylesheet" href="../assets/css/viz-1.0.1.css">
    <link rel="stylesheet" href="../assets/css/visual.css">
    <link rel="stylesheet" href="../assets/css/drawgraph.css">


    <script src="../assets/js/jquery-3.3.1.min.js"></script>

</head>

<body class="page-body">
    <div class="page-container">
        <!-- add class"sidebar-collapsed" to close sidebar by default,"chat-visible" to make chat appear always -->

        <!-- Add"fixed" class to make the sidebar fixed always to the browser viewport. -->
        <!-- Adding class"toggle-others" will keep only one menu item open at a time. -->
        <!-- Adding class"collapsed" collapse sidebar root elements and show only icons. -->
        <div class="sidebar-menu toggle-others fixed">

            <div class="sidebar-menu-inner">

                <header class="logo-env">
                    <!-- logo -->
                    <div class="logo">
                        <a href="../" class="logo-expanded">
                            <img src="../assets/images/logo@2x.png" width="80" alt="" />
                        </a>

                        <a href="../" class="logo-collapsed">
                            <img src="../assets/images/logo-collapsed@2x.png" width="40" alt="" />
                        </a>
                    </div>
                 
                </header>
                <ul id="main-menu" class="main-menu">
                    <!-- add class"multiple-expanded" to allow multiple submenus to open -->
                    <!-- class"auto-inherit-active-class" will automatically add"active" class for parent elements who are marked already with class"active" -->
                    <li >
                        <a href="../index.html">
                            <i class="fa-home"></i>
                            <span class="title">首页</span>
                        </a>
                    </li>
                    <li>
                        <a href="../list/ll.html">
                            <i class="fa-chain"></i>
                            <span class="title">线性表</span>
                        </a>
                        <ul>
                            <li>
                                <a href="../list/ll.html">
                                    <span class="title">单链表</span>
                                </a>
                            </li>
                            <li>
                                <a href="../list/stack.html">
                                    <span class="title">栈</span>
                                </a>
                            </li>
                            <li>
                                <a href="../list/queue.html">
                                    <span class="title">队列</span>
                                </a>
                            </li>
                            <li>
                                <a href="../list/dll.html">
                                    <span class="title">双向链表</span>
                                </a>
                            </li>
                            <li>
                                <a href="../list/deque.html">
                                    <span class="title">双端队列</span>
                                </a>
                            </li>

                        </ul>
                    </li>
                    <li>
                        <a href="../tree/bst.html">
                            <i class="fa-sitemap"></i>
                            <span class="title">二叉树</span>
                        </a>
                        <ul>
                            <li>
                                <a href="../tree/bst.html">
                                    <span class="title">二叉搜索树</span>
                                </a>
                            </li>
                            <li>
                                <a href="../tree/avl.html">
                                    <span class="title">平衡二叉搜索树</span>
                                </a>
                            </li>
                            <li>
                                <a href="../tree/heap.html">
                                    <span class="title">堆</span>
                                </a>
                            </li>
                        </ul>
                    </li>
                    <li class="opened active">
                        <a href="../graph/graphds.html">
                            <i class="fa-share-alt"></i>
                            <span class="title">图</span>
                        </a>
                        <ul>
                            <li>
                                <a href="../graph/graphds.html">
                                    <span class="title">图的数据结构</span>
                                </a>
                            </li>
                            <li>
                                <a href="../graph/dfsbfs.html">
                                    <span class="title">图的遍历</span>
                                </a>
                            </li>
                            <li class="active">
                                <a href="../graph/mst.html">
                                    <span class="title">最小生成树</span>
                                </a>
                            </li>
                            <li>
                                <a href="../graph/sssp.html">
                                    <span class="title">最短路径</span>
                                </a>
                            </li>
                            <li>
                                <a href="../graph/maxflow.html">
                                    <span class="title">网络最大流</span>
                                </a>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <a href="../hashtable/lp.html">
                            <i class="fa-random"></i>
                            <span class="title">散列表</span>                          
                        </a>
                        <ul>
                            <li>
                                <a href="../hashtable/lp.html">
                                    <span class="title">线性探查</span>
                                </a>
                            </li>
                            <li>
                                <a href="../hashtable/qp.html">
                                    <span class="title">二次探查</span>
                                </a>
                            </li>
                            <li>
                                <a href="../hashtable/dh.html">
                                    <span class="title">双散列</span>
                                </a>
                            </li>
                            <li>
                                <a href="../hashtable/sc.html">
                                    <span class="title">分离链接</span>
                                </a>
                            </li>
                        </ul>
                    </li>
                    <li >
                        <a href="../sorting/bubble.html" >
                            <i class="fa-sort-amount-asc"></i>
                            <span class="title">排序</span>
                        </a>
                        <ul>
                            <li>
                                <a href="../sorting/bubble.html">
                                    <span class="title">冒泡排序</span>
                                </a>
                            </li>
                            <li>
                                <a href="../sorting/selection.html">
                                    <span class="title">选择排序</span>
                                </a>
                            </li>
                            <li>
                                <a href="../sorting/insertion.html">
                                    <span class="title">插入排序</span>
                                </a>
                            </li>
                            <li>
                                <a href="../sorting/merge.html">
                                    <span class="title">归并排序</span>
                                </a>
                            </li>
                            <li>
                                <a href="../sorting/quick.html">
                                    <span class="title">快速排序</span>
                                </a>
                            </li>
                            <li >
                                <a href="../sorting/radix.html" >
                                    <span class="title">基数排序</span>
                                </a>
                            </li>
                        </ul>
                    </li>             
                </ul>
            </div>
        </div>

        <div class="main-content">

            <!-- User Info, Notifications and Menu Bar -->
          
                <div class="row" style="margin:-30px -30px 0 -30px; background-color: #FFF; padding:15px 10px 10px; ">
                    <div class="col-auto">
                        <ul class="user-info-menu left-links list-inline list-unstyled">
                            <li class="hidden-sm hidden-xs">
                                <a href="#" data-toggle="sidebar">
                                    <i class="fa-bars"></i>
                                </a>
                            </li>
                        </ul>        
                    </div>
                    <!-- Left links for user info navbar -->
                    <div class="col-auto">
                        <h4 id="page-title" >链表</h4>
                    </div>
                    <div class="col-auto me-auto">
                        <div id="current-action" ></div>
                    </div>               
                    <div class="col-auto" >
                                    <!-- Right links for user info navbar -->              
                        <div id="speed-control">
                            减速
                            <div id="speed-input" class="ui-slider ui-corner-all ui-slider-horizontal ui-widget ui-widget-content">
                                <span tabindex="0" class="ui-slider-handle ui-corner-all ui-state-default" style="left: 72.2222%;"></span>
                            </div>
                            加速
                        </div>              
                    </div>
                </div>
            

            <script type="text/javascript">
                jQuery(document).ready(function($) {     
                    // Charts
                    var xenonPalette = ['#68b828', '#7c38bc', '#0e62c7', '#fcd036', '#4fcdfc', '#00b19d', '#ff6264', '#f7aa47'];
                    // Pageviews Visitors Chart
                  
                      
                     
                    $("#page-title").text('最小生成树');
                });             
                
            </script>

            <div class="row">

              
                <div id="dark-overlay"></div>


                <div id="viz">

                </div>
                

                <div id="overlay" hidden="" style="opacity: 0; display: none;"></div>


                <div id="popup" hidden="">
                    <div id="popup-content"></div>
                    <span id="hide-popup" hidden="" style="background-color: rgb(255, 138, 39);">X <u>关闭</u></span>
                </div>
         

                <script>
                    var PHP_DOMAIN ="";

                    // surprise colour!
                    // Referenced to in  home.js and viz.js also
                    var colourArray = ["#52bc69","#d65775" /*"#ed5a7d"*/ ,"#2ebbd1","#d9513c","#fec515","#4b65ba","#ff8a27","#a7d41e"]; // green, pink, blue, red, yellow, indigo, orange, lime

                    function disableScroll() {
                        $('html').css('overflow', 'hidden');
                    }

                    function enableScroll() {
                        $('html').css('overflow', 'visible');
                    }

                    function replaceAll(find, replace, str) {
                        return str.replace(new RegExp(find, 'g'), replace);
                    }

                    function getColours() {
                        var generatedColours = new Array();
                        while (generatedColours.length < 4) {
                            var n = (Math.floor(Math.random() * colourArray.length));
                            if ($.inArray(n, generatedColours) == -1)
                                generatedColours.push(n);
                        }
                        return generatedColours;
                    }

                    function isOn(value, position) {
                        return (value >> position) & 1 === 1;
                    }

                    function customAlert(msg) {
                        $('#custom-alert p').html(msg);
                        var m = -1 * ($('#custom-alert').outerHeight() / 2);
                        $('#custom-alert').css('margin-top', m + 'px');
                        $('#dark-overlay').fadeIn(function() {
                            $('#custom-alert').fadeIn(function() {
                                setTimeout(function() {
                                    $('#custom-alert').fadeOut(function() {
                                        $('#dark-overlay').fadeOut();
                                    });
                                }, 1000);
                            });
                        });
                    }

                    function showLoadingScreen() {
                        $('#loading-overlay').show();
                        $('#loading-message').show();
                    }

                    function hideLoadingScreen() {
                        $('#loading-overlay').hide();
                    }

                    function commonAction(retval, msg) {
                        //setTimeout(function() {
                        if (retval) { // mode =="exploration" && // now not only for exploration mode, but check if this opens other problems
                         
                            $('#current-action').html(mode =="exploration" ? msg : ("e-Lecture Example (auto play until done)<br>" + msg));
                            $('#progress-bar').slider("option","max", gw.getTotalIteration() - 1);
                            triggerRightPanels();
                            isPlaying = true;
                        }
                        //}, 500);
                    }

                    function getQueryVariable(variable) {
                        var query = window.location.search.substring(1);
                        var vars = query.split('&');
                        for (var i = 0; i < vars.length; i++) {
                            var pair = vars[i].split('=');
                            if (decodeURIComponent(pair[0]) == variable)
                                return decodeURIComponent(pair[1]);
                        }
                        return"";
                    }

                    var generatedColours = getColours();
                    var surpriseColour = colourArray[generatedColours[0]];
                    var colourTheSecond = colourArray[generatedColours[1]];
                    var colourTheThird = colourArray[generatedColours[2]];
                    var colourTheFourth = colourArray[generatedColours[3]];

                    $(function() {
                       

                        // title
                        $('#title a').click(function() {
                            $('#title a').removeClass('selected-viz');
                            $(this).addClass('selected-viz');
                            // temporary quick fix for Google Chrome Aug 2016 issue...
                            setTimeout(function() {
                                document.body.style.zoom ="100.1%";
                            }, 100); // force resize/redraw...
                            setTimeout(function() {
                                document.body.style.zoom ="100%";
                            }, 600);
                        });

                        // overlays stuffs
                        $('#trigger-about').click(function() {
                            if ($(window).width() > 600) {
                                $('#dark-overlay').fadeIn(function() {
                                    $('#about').fadeIn();
                                });
                            } else
                                alert('Sorry, this dialog is too big. Please load it on bigger screen');
                        });

                        $('#trigger-team').click(function() {
                            if ($(window).width() > 600) {
                                $('#dark-overlay').fadeIn(function() {
                                    $('#team').fadeIn();
                                });
                            } else
                                alert('Sorry, this dialog is too big. Please load it on bigger screen');
                        });

                        $('#trigger-terms').click(function() {
                            if ($(window).width() > 600) {
                                $('#dark-overlay').fadeIn(function() {
                                    $('#termsofuse').fadeIn();
                                });
                            } else
                                alert('Sorry, this dialog is too big. Please load it on bigger screen');
                        });

                        $('.close-overlay').click(function() {
                            $('.overlays').fadeOut(function() {
                                $('#dark-overlay').fadeOut();
                            });
                        });

                        $('#dark-overlay').click(function() {
                            $('.overlays').fadeOut();
                            $('#dark-overlay').fadeOut();
                        });
                    });
                </script>




                <script>
                    window.onpopstate = function(event) {
                        var slide = event.state['slide'];
                        openSlide(slide, function() {
                            runSlide(slide);
                        });
                    };

                    function getUrlParameter(sParam) {
                        var sPageURL = decodeURIComponent(window.location.search.substring(1)),
                            sURLVariables = sPageURL.split('&'),
                            sParameterName, i;

                        for (i = 0; i < sURLVariables.length; i++) {
                            sParameterName = sURLVariables[i].split('=');
                            if (sParameterName[0] === sParam) return sParameterName[1] === undefined ? true : sParameterName[1];
                        }
                    };

                    function pushState(slideValue) {
                        var url = '/zh/list';
                        if (typeof slideValue != 'undefined' && slideValue != null) url += '?slide=' + slideValue;
                        window.history.pushState({
                            slide: slideValue
                        },"slide" + slideValue, url);
                    }

                    function showPopup(callback) {
                        $('#popup').fadeIn(100, callback);
                    }

                    function hidePopup(callback) {
                        $('#popup').fadeOut(100, callback);
                    }

                    $(function() {
                        var slide = getUrlParameter('slide');

          

                        $('.mcq-submit').click(function() {
                            var questionId = parseInt($(this).attr('id').split('-')[1]);
                            var answer = $('#mcq-answer-' + questionId).val();
                            var userAnswer = $('input[type=radio][name=mcq-' + questionId + '-choice]:checked').val();

                            if (answer === userAnswer) {
                                $('#answer-status-' + questionId).html('<font color="green"><b>Correct!</b></font>');
                            } else {
                                $('#answer-status-' + questionId).html('<font color="red"><b>Wrong Answer! Try again...</b></font>');
                            }
                            $('#answer-status-' + questionId).show();
                            setTimeout(function() {
                                $('#answer-status-' + questionId).fadeOut(1000);
                            }, 1000);
                        });

                        $('.msq-submit').click(function() {
                            var questionId = parseInt($(this).attr('id').split('-')[1]);
                            var answer = $('#msq-answer-' + questionId).val();

                            var answers = [];
                            $('input[type=checkbox][class=msq-choice]:checked').each(function() {
                                answers.push($(this).attr('id').split('-')[3]);
                            });
                            answers.sort();
                            var userAnswer = answers.join(',');

                            if (answer === userAnswer) {
                                $('#answer-status-' + questionId).html('<font color="green">Correct!</font>');
                            } else {
                                $('#answer-status-' + questionId).html('<font color="red">Wrong Answer! Try again...</font>');
                            }
                            $('#answer-status-' + questionId).show();
                            setTimeout(function() {
                                $('#answer-status-' + questionId).fadeOut(1000);
                            }, 1000);
                        });

                      

                        $('#hide-popup').click(function() {
                            hidePopup();
                        });

                        $('#popup').hover(function() {
                            $('#hide-popup').show();
                        }, function() {
                            $('#hide-popup').hide();
                        });




                        // temporary quick fix for Google Chrome Aug 2016 issue..., put at last part so that everything else has been loaded
                        // setTimeout(function(){ document.body.style.zoom ="100.1%"; }, 500);
                        // setTimeout(function(){ document.body.style.zoom ="100%"; }, 600);
                        // I turn it off on 14 June 2018, seems 'ok'?
                    });

               

                    function adjustPopupToImageSize() {
                        var width = $('#popup-image').prop('width');
                        var height = $('#popup-image').prop('height');
                        $('#popup').width(width + 20);
                        $('#popup').height(height + 20);
                        if (width == 0 && height == 0) {
                            setTimeout(adjustPopupToImageSize, 200);
                        } else {
                            showPopup();
                        }
                    }

                    function POPUP_IMAGE(url) {
                        $('#popup-content').html('<img id="popup-image" src="' + url + '">');
                        adjustPopupToImageSize();
                    }

                    function URL(url) {
                        window.open(url, '_blank');
                    }

                </script>


            </div>






            <!-- Main Footer -->
            <!-- Choose between footer styles:"footer-type-1" or"footer-type-2" -->
            <!-- Add class"sticky" to  always stick the footer to the end of page (if page contents is small) -->
            <!-- Or class"fixed" to  always fix the footer to the end of page -->
            <footer class="main-footer sticky footer-type-2 sticky fixed">

                <div class="footer-inner">
                    <div class="row">
                        <div class="col-auto">
                            <div class="btn-group dropdown dropup">                               
                                <a id="actions-toggle" class="btn btn-sm btn-info dropdown-toggle " data-bs-toggle="dropdown"  data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">                            
                                    操作                                                      
                                </a>                                    
                                <div id="actions" class="dropdown-menu">
                                    <div class="dropdown dropend">
                                        <a id="search" class="dropdown-item " onclick="drawGraph()" >
                                            绘制图</a>                                        
                                    </div>
                                    <div class="dropdown dropend">                                        
                                        <a id="create" class="dropdown-item dropdown-toggle" href="#"_id="dropdown-create" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">创建</a>
                                        <div class="dropdown-menu" aria-labelledby="dropdown-create">
                                            <div class="dropdown-item" onclick="example(CP3_4_10);" >
                                                <a>连通无向图1</a>
                                            </div>
                                            <div class="dropdown-item" onclick="example(CP3_4_14);">
                                                <a>连通无向图2</a>
                                            </div>
                                            <div class="dropdown-item" onclick="example(K5);">
                                                <a>无向图K5</a>
                                            </div>
                                            <div class="dropdown-item" onclick="example(RAIL);" >
                                                <a>轨道形无向图</a>
                                            </div>
                                            <div class="dropdown-item" onclick="example(TESSELLATION);" >
                                                <a>细分曲面无向图</a>
                                            </div>
                                                        
                                        </div>
                                    </div>
                                    <div class="dropdown-item" onclick="kruskals();">
                                        <a>克鲁斯卡尔算法</a>
                                    </div>
                                    <div class="dropdown dropend">
                                        <a id="insert" class="dropdown-item dropdown-toggle" href="#"_id="dropdown-insert" data-bs-toggle="dropdown" aria-haspopup="true"   aria-expanded="false">
                                            普里姆算法</a>
                                        <div class="dropdown-menu " aria-labelledby="dropdown-insert" style="min-width: 200px;">
                                            <div  class="dropdown-item-text" >
                                                起始结点
                                            </div>   
                                            <div id="insert-head" class="dropdown-item-text" >
                                                <input type="number" id="prim-v" title="Enter an Integer" autocomplete="off" min="0" max="99" value="0">
                                                <div id="inserthead-go" class="btn btn-sm btn-blue " onclick="prims()" >
                                                    执行
                                                </div>                                          
                                            </div>                                           
                                        </div>  
                                    </div>
                                </div>
                            </div>
                        </div>
                        
                        <div class="col-auto">
                            <span id="go-to-beginning" class="media-control-button" title="go to beginning" onclick="goToBeginning()"><img
                                src="../assets/images/goToBeginning.png" alt="go to beginning"></span>
                        </div>
                        <div class="col-auto">
                            <span id="previous" class="media-control-button" title="step backward" onclick="stepBackward()"><img
                                src="../assets/images/prevFrame.png" alt="previous frame"></span>
                        </div>
                        <div class="col-auto">
                            <span id="pause" class="media-control-button" title="pause" onclick="pause()" ><img
                                src="../assets/images/pause.png" alt="pause"></span>
                            <span id="play" class="media-control-button" title="play" onclick="play()" style="display: none;">
                                <img src="../assets/images/play.png" alt="play"></span>
                        </div>
                        <div class="col-auto">
                            <span id="next" class="media-control-button" title="step forward" onclick="stepForward()"><img
                                src="../assets/images/nextFrame.png" alt="next frame"></span>
                        </div>
                        <div class="col-auto">
                            <span id="go-to-end" class="media-control-button" title="go to end" onclick="goToEnd()"><img
                                src="../assets/images/goToEnd.png" alt="go to end"></span>
                        </div>


                        <div class="col-5 me-auto">
                            <div id="progress-bar" class="slider ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all" data-min="0" data-max="1800" data-value="223">
                            </div>

                        </div>
                        <div class="col-auto">
                            <div class="btn-group dropdown dropup">
                                <a id="codetrace-toggle" class="btn btn-sm btn-warning dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="false" aria-expanded="false" data-bs-offset="0,20">                            
                                    代码跟踪
                                                  
                                </a>
                                <div id="codetrace-panel" class="dropdown-menu dropdown-menu-end">
                                    <div class="row" style="width: 600px;">
                                        <div class="col-sm-12">
                                            <div id="status" class=" col-sm-12" >
                                                <p></p>
                                            </div>
                                            <div id="codetrace" class=" col-sm-12">
                                                <p id="code1" style="padding-top: 10px; background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code2" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code3" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code4" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code5" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code6" style="background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                                <p id="code7" style="padding-bottom: 10px; background-color: rgb(82, 188, 105); color: rgb(255, 255, 255);"></p>
                                            </div>
                                        </div>
                                    </div>
                                </div>

                            </div>
                        </div>
                     </div>  
            </footer>
        </div>
    </div>    

    <div class="page-loading-overlay">
        <div class="loader-2"></div>
    </div>

    <div id="drawgraph" class="overlays" style="display: none;">  
        <script>var JSONresult;</script>    
        <div id="main">      
            <div id="draw-status">
                <p>绘制具有不同属性的图，然后尝试在其图上运行各种图的遍历算法。
                    <div>默认绘图模式是有向图（每个边有一个或最多两个箭头）。
                </div>
            </p>
        </div>      
        <div id="draw-warn"><p>没有警告</p></div>      
        <div id="draw-err"><p>没有错误</p></div>      
        <div id="viz">        
            <svg onclick="GraphVisu(false,true,null,null,null,true); " width="640" height="360">
                <defs><marker id="end-arrow" viewBox="0 -5 10 10" refX="6" markerWidth="3" markerHeight="3" orient="auto">
                    <path d="M0,-5L10,0L0,5" fill="#000"></path></marker></defs><path class="link dragline hidden" d="M0,0L0,0"></path>
                    <g><path class="link" d="M108.48528137423857,108.48528137423857L191.51471862576142,191.51471862576142"></path>
                        <path class="link" d="M208.48528137423858,208.48528137423858L291.5147186257614,291.5147186257614"></path>
                    </g>
                    <g>
                        <g><circle class="node" r="16" cx="100" cy="100" style="fill: rgb(238, 238, 238);"></circle>
                            <text x="100" y="105.33333333333333" class="id">0</text>
                        </g>
                        <g><circle class="node" r="16" cx="200" cy="200" style="fill: rgb(238, 238, 238);"></circle>
                                <text x="200" y="205.33333333333334" class="id">1</text>
                        </g>
                        <g><circle class="node" r="16" cx="300" cy="300" style="fill: rgb(238, 238, 238);"></circle>
                                    <text x="300" y="305.3333333333333" class="id">2</text>
                        </g>
                    </g>
                    <g></g>        
                    <text x="250" y="100"> • 单击空白处增加新结点</text>        
                    <text x="250" y="125"> • 在两个结点之间按住左键拖动连线以增加新的边</text>        
                    <text x="250" y="150"> • 选中结点按Delete键删除结点</text>        
                    <text x="250" y="175"> • 选中边按 Enter 更改边的权重</text>      
                </svg>    
            </div>    
            <div id="drawgraph-actions">      
                <p onclick="drawCancel()">取消绘制</p>      
                <p onclick="GraphVisu(false,true,true)">消除</p>      
                <p onclick="drawDone()">绘制完成</p>      
                <form id="drawgraph-form">        
                    <!--<input type="checkbox" id="submit" name="submit" value="submit" checked="checked">Submit drawn graph to database for random graph and online quiz purposes        <br>-->
                    <input type="checkbox" id="copy" name="submit" value="submit">导出到剪贴板      
                </form>    
            </div>  
        </div>
    </div>


    <!-- Bottom Scripts -->
    <script src="../assets/js/bootstrap.bundle.js"></script>
    <script src="../assets/js/bootstrap5.dropdown.ml.hack.js"></script>
    <script src="../assets/js/TweenMax.min.js"></script>
    <script src="../assets/js/resizeable.js"></script>
    <script src="../assets/js/joinable.js"></script>
    <script src="../assets/js/xenon-api.js"></script>
    <script src="../assets/js/xenon-toggles.js"></script>


    <!-- Imported scripts on this page -->
    <script src="../assets/js/xenon-widgets.js"></script>
    <script src="../assets/js/devexpress-web-14.1/js/globalize.min.js"></script>
    <!--   <script src="../assets/js/devexpress-web-14.1/js/dx.chartjs.js"></script>-->
    <script src="../assets/js/toastr/toastr.min.js"></script>


    
    <script src="../assets/js/jquery-ui/jquery-ui.js"></script>
    <script src="../assets/js/knob/jquery.knob.min.js"></script>

    <!-- JavaScripts initializations and stuff -->
    <script src="../assets/js/xenon-custom.js"></script>
    
    <script src="../assets/js/d3.min.js"></script>
    <script src="../assets/js/viz-1.0.3.js"></script>
    <script src="../assets/js/visualgo_print.js"></script>
    <script src="../assets/js/graph_library.js"></script>
    <script type="text/javascript">
        // MST Widget
        // original author: Ivan Reinaldo, then maintained by Steven Halim
        
        var MST = function() {
          var self = this;
          var gw = new GraphWidget();
        
          var iVL = {};
          var iEL = {};
          var iAL = {}; // special, for Prim's
          var amountVertex = 0;
          var amountEdge = 0;
        
          this.getGraphWidget = function() { return gw; }
        
          fixJSON = function() {
            amountVertex = 0;
            amountEdge = 0;
            for (var key in iVL) amountVertex++;
            for (var key in iEL) amountEdge++;
        
            var sortedArray = [];
            for (key in iEL) {
              sortedArray.push(new ObjectTriple(parseInt(iEL[key]["w"]), parseInt(iEL[key]["u"]), parseInt(iEL[key]["v"])));
            }
            sortedArray.sort(ObjectTriple.compare); // sort by increasing w, and if ties, by increasing u, and if still ties, by increasing v
        
            for (var i = 0; i < sortedArray.length; i++) { // rearrange the keys in iEL based on our custom sort order
              iEL[i]["w"] = sortedArray[i].getFirst();
              iEL[i]["u"] = sortedArray[i].getSecond();
              iEL[i]["v"] = sortedArray[i].getThird();
            }
        
            for (var key in iVL) iAL[key] = Array();
            for (var key in iEL) { // transform EL to AL (for Prim's)
              iAL[iEL[key]["u"]].push(new ObjectTriple(iEL[key]["v"], iEL[key]["w"], key));
              iAL[iEL[key]["v"]].push(new ObjectTriple(iEL[key]["u"], iEL[key]["w"], key)); // bidirectional
            }
          }
        
          takeJSON = function(graph) {
            if (graph == null) return;
            graph = JSON.parse(graph);
            iVL = graph["vl"];
            iEL = graph["el"];
            fixJSON();
          }
        
          statusChecking = function() {
            $("#draw-status p").html("Draw a <b>connected undirected weighted</b> graph, preferably <b>V > 7</b>, <b>minimize edge crossing</b>, and make it <b>challenging for Prim&#39;s/Kruskal&#39;s algorithm</b>");
          }
        
          warnChecking = function() {
            var warn = "";
            if (amountVertex >= 17) warn += "Too much vertex on screen, consider drawing smaller graph. ";
            if (warn == "") $("#draw-warn p").html("No Warning");
            else            $("#draw-warn p").html(warn);
          }
        
          errorChecking = function() {
            var error = "";
            if (amountVertex == 0) {
              $("#draw-err p").html("Graph cannot be empty. ");
              return;
            }
        
            if (amountVertex == 1) {
              $("#draw-err p").html("Graph must contain at least one edge. ");
              return;
            }
        
            var visited = [];
            var stack = [];
            stack.push(0);
            visited[0] = true;
            while (stack.length > 0) {
              var now = stack.pop();
              for (var key2 in iEL) {
                if (iEL[key2]["u"] == now && !visited[iEL[key2]["v"]]) {
                  visited[iEL[key2]["v"]] = true;
                  stack.push(+iEL[key2]["v"]);
                }
                if (iEL[key2]["v"] == now && !visited[iEL[key2]["u"]]) {
                  visited[iEL[key2]["u"]] = true;
                  stack.push(+iEL[key2]["u"]);
                }
              }
            }
        
            for (var i = 0; i < amountVertex; i++)
              if (!visited[i]) {
                error = error + "Vertex 0 and vertex {i} is not connected. ".replace("{i}", i);
                break;
              }
        
            if (error == "") $("#draw-err p").html("Graph must contain at least one edge. ");
            else             $("#draw-err p").html(error);
          }
        
          var intervalID;
        
          this.startLoop = function() {
            intervalID = setInterval(function() {
              takeJSON(JSONresult);
              warnChecking();
              errorChecking();
              statusChecking();
            }, 100);
          }
        
          this.stopLoop = function() {
            clearInterval(intervalID);
          }
        
          this.draw = function() {
            if ($("#draw-err p").html() != "Graph must contain at least one edge. ")
              return false;
            if ($("#submit").is(':checked'))
              this.submit(JSONresult);
            if ($("#copy").is(':checked'))
              window.prompt("Copy to clipboard:", JSONresult);
        
            fixJSON(); // to re-sort the edges
        
            graph = createState(iVL, iEL);
            gw.updateGraph(graph, 500);
            return true;
          }
        
          this.importjson = function(text) {
            takeJSON(text);
            statusChecking();
            graph = createState(iVL, iEL);
            gw.updateGraph(graph, 500);
          }
        
        
        
          this.getGraph = function() {
            return {
              'vl': iVL,
              'el': iEL
            };
          }
        
          this.getV = function() {
            return amountVertex;
          }
        
          this.kruskal = function(callback) {
            var i, key, totalWeight = 0, cs;
            var stateList = [], sortedArray = [];
            var vertexHighlighted = {}, edgeHighlighted = {}, vertexTraversed = {}, edgeTraversed = {}, edgeQueued = {};
            var tempUfds = new UfdsHelper();
        
            if (amountVertex == 0) { // error check, no graph (maybe via empty JSON or faulty db)
              $('#kruskals-err').html("没有图运行此项。请先创建图。");
              return false;
            }
        
            for (key in iVL) tempUfds.insert(key);
        
            for (key in iEL) {
              edgeQueued[key] = true;
              sortedArray.push(new ObjectPair(parseInt(iEL[key]["w"]), parseInt(key)));
            }
            sortedArray.sort(ObjectPair.compare);
        
            function sortedArrayToString() {
              var ansStr = "";
              var maxLength = Math.min(sortedArray.length, 9);
              for (var i = 0; i < maxLength; i++) {
                var thisEdgeId = sortedArray[i].getSecond();
                ansStr += "(" + iEL[thisEdgeId]["w"] + ",(" + iEL[thisEdgeId]["u"] + "," + iEL[thisEdgeId]["v"] + "))";
                if (i < (maxLength-1)) ansStr += ", ";
              }
              if (sortedArray.length > 10) ansStr += " ...";
              return ansStr;
            }
        
            cs = createState(iVL, iEL);
            cs["status"] = "按照边权升序排序边: " + sortedArrayToString() + ".";
            cs["lineNo"] = [1, 2];
            stateList.push(cs);
        
            numTaken = 0;
            while (sortedArray.length > 0) {
              cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
              cs["status"] = "剩余边集为： " + sortedArrayToString() + ".";
              cs["lineNo"] = 3;
              stateList.push(cs);
        
              var dequeuedEdge = sortedArray.shift();
              var dequeuedEdgeId = dequeuedEdge.getSecond();
              var u = iEL[dequeuedEdgeId]["u"], v = iEL[dequeuedEdgeId]["v"], w = parseInt(iEL[dequeuedEdgeId]["w"]);
        
              edgeHighlighted[dequeuedEdgeId] = true;
              vertexHighlighted[u] = true;
              vertexHighlighted[v] = true;
        
              cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
              cs["status"] = "检查增加此边后是否有环: (" + w + ",(" + u + "," + v + ")).";
              cs["lineNo"] = 4;
              stateList.push(cs);
        
              var noCycle = false;
              if (!tempUfds.isSameSet(u, v)) {
                noCycle = true;
                tempUfds.unionSet(u, v);
                edgeTraversed[dequeuedEdgeId] = true;
                vertexTraversed[u] = true;
                vertexTraversed[v] = true;
                totalWeight += w;
              }
        
              delete edgeHighlighted[dequeuedEdgeId];
              delete edgeQueued[dequeuedEdgeId]
              delete vertexHighlighted[u];
              delete vertexHighlighted[v];
        
              cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
              if (noCycle) {
                cs["status"] = "加入边后无环，故将边加入 T。  T 的总边权为 " + totalWeight + ".";
                cs["lineNo"] = 5;
                numTaken++;
              }
              else {
                cs["status"] = " 加入边后有环，故不能加入边。  T 的总边仍为 " + totalWeight + ".";
                cs["lineNo"] = 6;
              }
              stateList.push(cs);
        
              if (noCycle && (numTaken == amountVertex-1)) {
                cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
                cs["status"] = (amountVertex-1) + " 条边已经利用 Kruskal算法找到, 故找到最小生成树.<br>优化后 Kruskal算法可在此时停止."; // the animation will still run until the end
                cs["lineNo"] = 5;
                stateList.push(cs);
              }
            }
        
            cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
            cs["status"] = "高亮的结点和边构成了最小生成树，其总权重为 " + totalWeight + ".<br>";
            cs["lineNo"] = 7;
            stateList.push(cs);
        
            populatePseudocode(1);
            gw.startAnimation(stateList, callback);
            return true;
          }
        
          this.prim = function(sourceVertex, callback) {
            var i, key, totalWeight = 0, cs;
            var visited = {}, vertexHighlighted = {}, edgeHighlighted = {}, vertexTraversed = {}, edgeTraversed = {}, edgeQueued = {};
            var stateList = [];
        
            // error checks
            if (amountVertex == 0) { // no graph
               toastr.error("没有图表运行此项。请首先选择图表。.");
              return false;
            }
        
            if (sourceVertex >= amountVertex || sourceVertex < 0) { // start vertex not in range
               toastr.error("所输入的结点在图中不存在。");
              return false;
            }
        
            for (key in iVL) visited[key] = false;
            vertexTraversed[sourceVertex] = true;
            for (var key in iVL) iVL[key]["extratext"] = "";
            iVL[sourceVertex]["extratext"] = "source";
            cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
            cs["status"] = "T = {" + sourceVertex + "}.";
            cs["lineNo"] = 1;
            stateList.push(cs);
        
            delete vertexHighlighted[sourceVertex];
            vertexTraversed[sourceVertex] = true;
        
            var sortedArray = [];
            var enqueuedToString = "";
        
            function sortedArrayToString() {
              var ansStr = "";
              var maxLength = Math.min(sortedArray.length, 6);
              for (var i = 0; i < maxLength; i++) {
                var thisTriple = sortedArray[i];
                ansStr += "(" + thisTriple.getFirst() + "," + thisTriple.getSecond() + ")";
                if (i < (maxLength-1)) ansStr += ", ";
              }
              if (sortedArray.length > 6) ansStr += "..";
              if (ansStr == "") ansStr = "empty";
              return ansStr;
            }
        
            function process(vtx) {
              enqueuedToString = "";
              visited[vtx] = true;
              for (key in iAL[vtx]) {
                var v = iAL[vtx][key].getFirst();
                var w = iAL[vtx][key].getSecond();
                var enqueuedEdgeId = iAL[vtx][key].getThird();
                if (!visited[v]) {
                  enqueuedEdge = new ObjectTriple(parseInt(w), parseInt(v), parseInt(enqueuedEdgeId));
                  edgeQueued[enqueuedEdgeId] = true;
                  enqueuedToString += "(" + w + "," + v + "), ";
                  sortedArray.push(enqueuedEdge);
                }
              }
              enqueuedToString = enqueuedToString.substring(0, enqueuedToString.length-2);
              sortedArray.sort(ObjectTriple.compare);
            }
        
            process(sourceVertex);
        
            cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
            cs["status"] = enqueuedToString + " 加入到优先队列PQ。<br> PQ 现为 " + sortedArrayToString() + ".";
            cs["lineNo"] = 2;
            stateList.push(cs);
        
            var numTaken = 1;
            while (sortedArray.length > 0) {
              var dequeuedEdge = sortedArray.shift();
              var otherVertex = dequeuedEdge.getSecond();
              var edgeId = dequeuedEdge.getThird();
        
              vertexHighlighted[otherVertex] = true;
              edgeHighlighted[edgeId] = true;
              cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
              cs["status"] = "(" + dequeuedEdge.getFirst() + "," + otherVertex + ") 从优先队列PQ中删除. 检察结节 " + otherVertex + " 在 T中.<br> PQ 现为 " + sortedArrayToString() + ".";
              cs["lineNo"] = 4;
              stateList.push(cs);
        
              if (!visited[otherVertex]) {
                delete edgeHighlighted[edgeId];
                edgeHighlighted[edgeId] = true;
                vertexHighlighted[otherVertex] = true;
        
                cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
                cs["status"] = otherVertex + " 不在 T中。";
                cs["lineNo"] = 4;
                stateList.push(cs);
        
                delete vertexHighlighted[otherVertex];
                delete edgeHighlighted[edgeId];
                edgeTraversed[edgeId] = true;
                vertexTraversed[otherVertex] = true;
        
                process(otherVertex);
        
                totalWeight += parseInt(dequeuedEdge.getFirst());
                cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
                cs["status"] = otherVertex + " 结点以及此边加入T中 (T\\&#39;s weight = " + totalWeight + "), " + (enqueuedToString.length > 0 ? enqueuedToString : "(null)") + " 也加入到优先队列 PQ中。  PQ现为 " + sortedArrayToString() + ".";
                cs["lineNo"] = 5;
                stateList.push(cs);
        
                numTaken++;
                if (numTaken == amountVertex) { // to show that we can optimize Prim's a bit.
                  cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
                  cs["status"] = numTaken + " 个结点已经通过 Prim算法发现, 故最小生成树已经找到.<br>优化后的 Prim算法可在此结束."; // For now, we will continue until the PQ is empty
                  cs["lineNo"] = 5;
                  stateList.push(cs);
                }
              }
              else {
                delete edgeQueued[edgeId];
                delete edgeHighlighted[edgeId];
        
                cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
                cs["status"] = otherVertex + " 已经在T中，故忽略此边。";
                cs["lineNo"] = 6;
                stateList.push(cs);
              }
            }
        
            cs = createState(iVL, iEL, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued);
            cs["status"] = "高亮的结点和边构成了最小生成树，其总权重为 " + totalWeight + '.<br>';
            cs["lineNo"] = 7;
            stateList.push(cs);
        
            populatePseudocode(0);
            gw.startAnimation(stateList, callback);
            return true;
          }
        
          this.examples = function(id) {
            var vertexList = getExampleGraph(id, VL);
            var edgeList = getExampleGraph(id, EL);
            this.loadGraph(vertexList, edgeList);
            return true;
          }
        
          this.loadGraph = function(vertexList, edgeList) {
            iVL = vertexList;
            iEL = edgeList;
            fixJSON();
            var newState = createState(iVL, iEL);
            gw.updateGraph(newState, 500);
          }
        
          function createState(iVLObject, iELObject, vertexHighlighted, edgeHighlighted, vertexTraversed, edgeTraversed, edgeQueued) {
            var isDefaultGrey = true;
            if ((vertexHighlighted == null) && (edgeHighlighted == null) && (vertexTraversed == null) && (edgeTraversed == null) && (edgeQueued == null))
              isDefaultGrey = false;
            if (vertexHighlighted == null) vertexHighlighted = {};
            if (edgeHighlighted == null) edgeHighlighted = {};
            if (vertexTraversed == null) vertexTraversed = {};
            if (edgeTraversed == null) edgeTraversed = {};
            if (edgeQueued == null) edgeQueued = {};
        
            var key;
            var state = {
              "vl": {},
              "el": {}
            };
        
            if (isDefaultGrey) {
              for (key in iVLObject) {
                state["vl"][key] = {};
                state["vl"][key]["cx"] = iVLObject[key]["x"];
                state["vl"][key]["cy"] = iVLObject[key]["y"];
                state["vl"][key]["text"] = key;
                state["vl"][key]["state"] = VERTEX_GREY_OUTLINE;
                state["vl"][key]["extratext"] = iVLObject[key]["extratext"];
              }
              for (key in iELObject) {
                state["el"][key] = {};
                state["el"][key]["vertexA"] = iELObject[key]["u"];
                state["el"][key]["vertexB"] = iELObject[key]["v"];
                state["el"][key]["type"] = EDGE_TYPE_UDE;
                state["el"][key]["weight"] = iELObject[key]["w"];
                state["el"][key]["state"] = EDGE_GREY;
                state["el"][key]["displayWeight"] = true;
                state["el"][key]["animateHighlighted"] = false;
              }
            }
            else {
              for (key in iVLObject) {
                state["vl"][key] = {};
                state["vl"][key]["cx"] = iVLObject[key]["x"];
                state["vl"][key]["cy"] = iVLObject[key]["y"];
                state["vl"][key]["text"] = key;
                state["vl"][key]["state"] = VERTEX_DEFAULT;
                state["vl"][key]["extratext"] = iVLObject[key]["extratext"];
              }
              for (key in iELObject) {
                state["el"][key] = {};
                state["el"][key]["vertexA"] = iELObject[key]["u"];
                state["el"][key]["vertexB"] = iELObject[key]["v"];
                state["el"][key]["type"] = EDGE_TYPE_UDE;
                state["el"][key]["weight"] = iELObject[key]["w"];
                state["el"][key]["state"] = EDGE_DEFAULT;
                state["el"][key]["displayWeight"] = true;
                state["el"][key]["animateHighlighted"] = false;
              }
            }
        
            for (key in edgeQueued) {
              key1 = state["el"][key]["vertexA"];
              key2 = state["el"][key]["vertexB"]
              state["vl"][key1]["state"] = VERTEX_DEFAULT;
              state["vl"][key2]["state"] = VERTEX_DEFAULT;
              state["el"][key]["state"] = EDGE_DEFAULT;
            }
        
            for (key in vertexHighlighted) state["vl"][key]["state"] = VERTEX_HIGHLIGHTED; // VERTEX_BLUE_FILL;
            for (key in edgeHighlighted) state["el"][key]["state"] = EDGE_HIGHLIGHTED; // EDGE_BLUE;
            for (key in vertexTraversed) state["vl"][key]["state"] = VERTEX_TRAVERSED; // VERTEX_GREEN_FILL;
            for (key in edgeTraversed) state["el"][key]["state"] = EDGE_TRAVERSED; // EDGE_GREEN;
        
            return state;
          }
        
          function populatePseudocode(act) {
            switch (act) {
              case 0: // Prim's
                $('#code1').html('T = {s}');
                $('#code2').html("enqueue edges connected to s in PQ (by inc weight)");
                $('#code3').html('while (!PQ.isEmpty)');
                $('#code4').html('&nbsp;&nbsp;if (vertex v linked with e = PQ.remove &notin; T)');
                $('#code5').html("&nbsp;&nbsp;&nbsp;&nbsp;T = T &cup; {v, e}, enqueue edges connected to v");
                $('#code6').html("&nbsp;&nbsp;else ignore e");
                $('#code7').html('MST = T ');
                break;
              case 1: // Kruskal's
                $('#code1').html("Sort E edges by increasing weight");
                $('#code2').html('T = {}');
                $('#code3').html('for (i = 0; i &lt; edgeList.length; i++)');
                $('#code4').html("&nbsp;&nbsp;if adding e = edgelist[i] does not form a cycle");
                $('#code5').html("&nbsp;&nbsp;&nbsp;&nbsp;add e to T");
                $('#code6').html("&nbsp;&nbsp;else ignore e");
                $('#code7').html('MST = T ');
                break;
            }
          }
        }
        
        
        
        // MST Actions
        var actionsWidth = 150;
        var statusCodetraceWidth = 430;
        
        var isExamplesOpen = false, isPrimsOpen = false;
        
        function openExamples() {
          if (!isExamplesOpen) {
            $('.examples').fadeIn('fast');
            isExamplesOpen = true;
          }
        }
        
        function closeExamples() {
          if (isExamplesOpen) {
            $('.examples').fadeOut('fast');
            isExamplesOpen = false;
          }
        }
        
        function openPrims() {
          if (!isPrimsOpen) {
            $('.prims').fadeIn('fast');
            isPrimsOpen = true;
          }
        }
        
        function closePrims() {
          if (isPrimsOpen) {
            $('.prims').fadeOut('fast');
             toastr.error("");
            isPrimsOpen = false;
          }
        }
        
        function hideEntireActionsPanel() {
          closeExamples();
          closePrims();
          hideActionsPanel();
        }
        
        
        
        // local
        write(true, false);
        var mw, gw, randomGraphID;
        
        $(function() {
          $('#play').hide();
          mw = new MST();
          gw = mw.getGraphWidget();
          var options = [CP3_4_10, CP3_4_14, K5, RAIL, TESSELLATION];
          mw.examples(options[Math.floor(Math.random()*5)]);
          randomGraphID = -1;
        
          var graphJSON = getQueryVariable("create");
          if (graphJSON.length > 0) {
            importjson(graphJSON);
            window.history.pushState("object or string", "Title", window.location.href.split('?')[0]);
          }
        
          $('#draw').click(function() {
            closeExamples();
            closePrims();
          });
        
          $('#random').click(function() {
            closeExamples();
            closePrims();
          });
        
          $('#examples').click(function() {
            openExamples();
            closePrims();
          })
        
          $('#kruskals').click(function() {
            closeExamples();
            closePrims();
          });
        
          $('#prims').click(function() {
            closeExamples();
            openPrims();
          });
        });
        
        function importjson(text) {
          if (isPlaying) stop();
          if (mode == "exploration") {
            mw.importjson(text);
            closeExamples();
            isPlaying = false;
          }
        }
        
        function drawGraph() {
          if (isPlaying) stop();
          if (mode == "exploration") {
            $('#dark-overlay').fadeIn(function() {
              $('#drawgraph').fadeIn();
            });
            mw.startLoop();
            isPlaying = false;
          }
        }
        
        function drawDone() {
          if (!mw.draw()) return false;
          mw.stopLoop();
          $('#drawgraph').fadeOut();
          $('#dark-overlay').fadeOut();
        }
        
        function drawCancel() {
          mw.stopLoop();
          $('#drawgraph').fadeOut();
          $('#dark-overlay').fadeOut();
        }
        
        // function createRandom() {
        //   if (isPlaying) stop();
        //   if (mode == "exploration") {
        //     $.ajax({
        //       url: PHP_DOMAIN + "/php/Graph.php?mode=" + MODE_GET_RANDOM_SUBMITTED_GRAPH + "&directed=" + 0 + "&connected=" + 1 // + "&topic=MST"
        //     }).done(function(data) {
        //       data = jQuery.parseJSON(data); // JSON.parse(data);
        //       var graph = extractQnGraph(data.graph);
        //       if (data.graphID == randomGraphID) // make sure it is different, make sure #graph > 1
        //         createRandom();
        //       randomGraphID = data.graphID;
        //       mw.initRandom(graph);
        //       $('#rate-sample-graph').show();
        //     })
        //     $('#progress-bar').slider("option", "max", 0);
        //     closeExamples();
        //     isPlaying = false;
        //   }
        // }
        
        function example(id) {
          if (isPlaying) stop();
          setTimeout(function() {
            if ((mode == "exploration") && mw.examples(id)) {
              $('#progress-bar').slider("option", "max", 0);
              closeExamples();
              isPlaying = false;
            }
          }, 500);
        }
        
        function kruskals(callback) {
          if (isPlaying) stop();
          commonAction(mw.kruskal(callback), "Kruskal&#39;s Algorithm");
        }
        
        function prims() {
          if (isPlaying) stop();
          var input = parseInt($('#prim-v').val());
          primsWithInput(input);
        }
        
        function primsWithInput(input, callback) {
          commonAction(mw.prim(input, callback), "Prim&#39;s Algorithm, s = " + input);
          setTimeout(function() { $('#prim-v').val(Math.floor(Math.random()*mw.getV())); }, 500); // randomized for next click between [0..V-1]
        }
        
        function loadGraph(graph) {
          if (mw) {
            mw.loadGraph(graph['vl'], graph['el']);
          }
        }
        
        // Implement these functions in each visualisation
        var userGraph = {
          'vl': {},
          'el': {},
        };
        
        // This function will be called before entering E-Lecture Mode
        function ENTER_LECTURE_MODE() {
          if (mw) userGraph = mw.getGraph();
        }
        
        // This function will be called before returning to Explore Mode
        function ENTER_EXPLORE_MODE() {
          loadGraph(userGraph);
        }
        
        // Lecture action functions
        function CUSTOM_ACTION(action, data, mode) {
          if (action == 'kruskal') {
            hideSlide(function() {
              kruskals(showSlide);
            });
          }
          else if (action == 'prim') {
            hideSlide(function() {
              primsWithInput(data, showSlide);
            });
          }
        }
        </script>
</body>

</html>